/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package org.freedom.railhunter.main;

import java.awt.Cursor;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.concurrent.ExecutionException;
import javax.swing.ImageIcon;
import javax.swing.JOptionPane;
import javax.swing.SwingWorker;
import org.apache.commons.lang3.StringUtils;
import org.freedom.railhunter.model.OrderConfiguration;
import org.freedom.railhunter.service.CookieService;
import org.freedom.railhunter.service.LoginService;
import org.freedom.railhunter.service.RandCodeService;
import org.freedom.railhunter.util.Des;
import org.slf4j.LoggerFactory;

/**
 *
 * @author Alan
 */
public class LoginFrame extends javax.swing.JFrame {
    
    private static final org.slf4j.Logger logger = LoggerFactory.getLogger(LoginFrame.class);
    
    private String loginUsername;

    /**
     * Creates new form LoginFrame
     */
    public LoginFrame() {
        this.setTitle("SnowWolf_Beta_23");
        this.setIconImage(new ImageIcon(getClass().getResource("/img/snow_wolf.jpg")).getImage());
        initComponents();
        new SwingWorker<ImageIcon, OrderConfiguration>() {

            @Override
            protected void process(List<OrderConfiguration> chunks) {
                if (!chunks.isEmpty()) {
                    OrderConfiguration orderConfiguration = chunks.get(0);
                    String username = orderConfiguration.get12306UserName();
                    String password = orderConfiguration.get12306Password();
                    if (StringUtils.isNotEmpty(username)) {
                        usernameField.setText(orderConfiguration.get12306UserName());
                    }
                    if (StringUtils.isNotEmpty(password)) {
                        try {
                            passwordField.setText(Des.decrypt(orderConfiguration.get12306Password()));
                        } catch (Exception ex) {
                            logger.error("", ex);
                        }
                    }
                }
            }
            
            @Override
            protected ImageIcon doInBackground() throws Exception {
                OrderConfiguration orderConfiguration = OrderConfiguration.getInstance();
                orderConfiguration.loadOrderConfig();
                publish(orderConfiguration);
                CookieService cookieService = CookieService.getInstance();
                Map<String, String> cookieData = cookieService.initCookie();
                RandCodeService randCodeService = RandCodeService.getInstance();
                byte[] imgBytes = randCodeService.buildRandCodeImageBytes(cookieData);
                return new ImageIcon(imgBytes);
            }
            
            @Override
            protected void done() {
                try {
                    codeImageLabel.setIcon(get());
                } catch (InterruptedException | ExecutionException ex) {
                    JOptionPane.showMessageDialog(LoginFrame.this, "获取验证码失败！请点击重新刷新。", "警告", JOptionPane.WARNING_MESSAGE);
                }
            }
            
        }.execute();
    }
    
    private void login() {
        loginUsername = usernameField.getText();
        okButton.setEnabled(false);
        cancelButton.setEnabled(false);
        this.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
        new SwingWorker<Boolean, Void>() {

            @Override
            protected Boolean doInBackground() throws Exception {
                LoginService loginService = LoginService.getInstance();
                return loginService.login(usernameField.getText(), new String(passwordField.getPassword()), 
                    randcodeField.getText().trim(), CookieService.getInstance().getCookieData());
            }

            @Override
            protected void done() {
                try {
                    if (get()) {
                        new SwingWorker<Boolean, Void>() {
                            @Override
                            protected Boolean doInBackground() throws Exception {
                                Properties orderCofnigProps = OrderConfiguration.getInstance().getOrderConfigProps();
                                orderCofnigProps.put(OrderConfiguration._12306_USERNAME_KEY, usernameField.getText().trim());
                                try {
                                    orderCofnigProps.put(OrderConfiguration._12306_PASSWORD_KEY, Des.encrypt(new String(passwordField.getPassword())));
                                } catch (Exception ex) {
                                    logger.error("", ex);
                                }
                                OrderConfiguration.getInstance().storeOrderConfig();
                                return true;
                            }
                        }.execute();
                        LoginFrame.this.setVisible(false);
                        MainFrame mainFrame = new MainFrame(loginUsername);
                        mainFrame.setLocationRelativeTo(null);
                        mainFrame.setVisible(true);
                    } else {
                        JOptionPane.showMessageDialog(LoginFrame.this, "登录失败！", "警告", JOptionPane.WARNING_MESSAGE);
                    }
                } catch (InterruptedException ex) {
                    JOptionPane.showMessageDialog(LoginFrame.this, "登录失败！登录过程被强制取消！", "警告", JOptionPane.WARNING_MESSAGE);
                } catch (ExecutionException ex) {
                    String message = ex.getCause().getMessage();
                    if (StringUtils.isEmpty(message)) {
                        JOptionPane.showMessageDialog(LoginFrame.this, " 网络可能存在问题！", "警告", JOptionPane.WARNING_MESSAGE);
                    } else {
                        JOptionPane.showMessageDialog(LoginFrame.this, ex.getCause().getMessage(), "警告", JOptionPane.WARNING_MESSAGE);
                    }
                } finally {
                    okButton.setEnabled(true);
                    cancelButton.setEnabled(true);
                    LoginFrame.this.setCursor(Cursor.getDefaultCursor());
                }
            }
            
        }.execute();
    }

    public String getLoginUsername() {
        return loginUsername;
    }
    
    /**
     * This method is called from within the constructor to initialize the form. WARNING: Do NOT
     * modify this code. The content of this method is always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        jLabel1 = new javax.swing.JLabel();
        jLabel2 = new javax.swing.JLabel();
        usernameField = new javax.swing.JTextField();
        jLabel3 = new javax.swing.JLabel();
        codeImageLabel = new javax.swing.JLabel();
        randcodeField = new javax.swing.JTextField();
        cancelButton = new javax.swing.JButton();
        okButton = new javax.swing.JButton();
        passwordField = new javax.swing.JPasswordField();

        setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
        setTitle("登录");

        jLabel1.setFont(new java.awt.Font("宋体", 0, 18)); // NOI18N
        jLabel1.setText("登录到12306");

        jLabel2.setText("用户名：");

        jLabel3.setText("密码：");

        codeImageLabel.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
        codeImageLabel.setIcon(new javax.swing.ImageIcon(getClass().getResource("/img/busy.png"))); // NOI18N
        codeImageLabel.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                codeImageLabelMouseClicked(evt);
            }
        });

        randcodeField.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                randcodeFieldActionPerformed(evt);
            }
        });

        cancelButton.setText("取消");
        cancelButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                cancelButtonActionPerformed(evt);
            }
        });

        okButton.setText("登录");
        okButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                okButtonActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(layout.createSequentialGroup()
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false)
                            .addComponent(jLabel3, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                            .addComponent(jLabel2, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(usernameField)
                            .addComponent(passwordField)))
                    .addGroup(layout.createSequentialGroup()
                        .addComponent(jLabel1)
                        .addGap(0, 0, Short.MAX_VALUE))
                    .addGroup(layout.createSequentialGroup()
                        .addComponent(codeImageLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 90, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addGap(18, 18, 18)
                        .addComponent(randcodeField, javax.swing.GroupLayout.DEFAULT_SIZE, 200, Short.MAX_VALUE))
                    .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                        .addGap(0, 0, Short.MAX_VALUE)
                        .addComponent(okButton)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(cancelButton)))
                .addContainerGap())
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                    .addComponent(randcodeField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addGroup(layout.createSequentialGroup()
                        .addComponent(jLabel1)
                        .addGap(18, 18, 18)
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                            .addComponent(jLabel2)
                            .addComponent(usernameField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                        .addGap(18, 18, 18)
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                            .addComponent(jLabel3)
                            .addComponent(passwordField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                        .addGap(18, 18, 18)
                        .addComponent(codeImageLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 40, javax.swing.GroupLayout.PREFERRED_SIZE)))
                .addGap(18, 18, 18)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(cancelButton)
                    .addComponent(okButton))
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );

        pack();
    }// </editor-fold>//GEN-END:initComponents

    private void cancelButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cancelButtonActionPerformed
        System.exit(0);
    }//GEN-LAST:event_cancelButtonActionPerformed

    private void okButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_okButtonActionPerformed
        login();
    }//GEN-LAST:event_okButtonActionPerformed

    private void randcodeFieldActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_randcodeFieldActionPerformed
        login();
    }//GEN-LAST:event_randcodeFieldActionPerformed

    private void codeImageLabelMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_codeImageLabelMouseClicked
        codeImageLabel.setIcon(new ImageIcon(getClass().getResource("/img/busy.png")));
        new SwingWorker<ImageIcon, Void>() {

            @Override
            protected ImageIcon doInBackground() throws Exception {
                RandCodeService randCodeService = RandCodeService.getInstance();
                byte[] imgBytes = randCodeService.buildRandCodeImageBytes(CookieService.getInstance().getCookieData());
                return new ImageIcon(imgBytes);
            }

            @Override
            protected void done() {
                try {
                    codeImageLabel.setIcon(get());
                } catch (InterruptedException | ExecutionException ex) {
                    JOptionPane.showMessageDialog(LoginFrame.this, "刷新验证码失败！", "警告", JOptionPane.WARNING_MESSAGE);
                }
            }
            
        }.execute();
    }//GEN-LAST:event_codeImageLabelMouseClicked

    /**
     * @param args the command line arguments
     */
    public static void main(String args[]) {
        /* Create and display the loginFrame */
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                final LoginFrame loginFrame = new LoginFrame();
                loginFrame.addWindowListener(new java.awt.event.WindowAdapter() {
                    @Override
                    public void windowClosing(java.awt.event.WindowEvent e) {
                        System.exit(0);
                    }
                });
                loginFrame.setLocationRelativeTo(null);
                loginFrame.setVisible(true);
            }
        });
    }
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton cancelButton;
    private javax.swing.JLabel codeImageLabel;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel2;
    private javax.swing.JLabel jLabel3;
    private javax.swing.JButton okButton;
    private javax.swing.JPasswordField passwordField;
    private javax.swing.JTextField randcodeField;
    private javax.swing.JTextField usernameField;
    // End of variables declaration//GEN-END:variables
}
